#pragma once

#include "timestamp.h"

#include <functional>
#include <memory>

class Timer : noncopyable {
    public:
        using TimerCallback = std::function<void()>;

        Timer(TimerCallback cb,Timestamp expiration,double interval)
            :callback_(std::move(cb)),
             expiration_(expiration),
             interval_(interval),
             repeat_(interval > 0.0){}

        //执行定时器回调
        void run() const {callback_();}

        //获取到期时间
        Timestamp expiration() const { return expiration_; }

        //是否重复触发
        bool repeat() const { return repeat_; }

        //计算下一次到期时间（重复定时器用）
        void restart(Timestamp now){
            if(repeat_){
                expiration_ = add_time(now,interval_);
            }
            else {
                expiration_  = Timestamp::now();//非重复定时器，置为当前时间（标记失效果）
            }

    private:
        //时间累加
        static Timestamp add_time(Timestamp now,double seconds){
            int64_t micro_seconds = static_cast<int64_t>(seconds * 1000000);
            return  Timestamp(now.microseconds_since_epoch() + micro_seconds);
        }

        const TimerCallback callback_; //定时回调函数
        Timestamp expiration_;         //到期时间
        const double interval_;        //重复间隔（秒，0 表示只触发一次）
        const bool repeat_;            //是否重复
}

using TimerPtr = std::shared_ptr<Timer>;